package com.g2room.driving.grap.life;

import java.io.IOException;
import java.net.MalformedURLException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.alibaba.fastjson.JSON;
import com.g2room.driving.grap.GenericGrap;
import com.g2room.driving.grap.life.model.po.ComCompany;
import com.g2room.driving.grap.life.model.po.ComType;
import com.g2room.myuall.grap.ky.model.po.GrapErr;
import com.g2room.myuall.util.DbUtil;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;

public class GrabQyxyCompanyDataByProxy implements Runnable {
	public String code = "";
	public String baseUrl = "";
	private String soruce = "企业信用网";


	@Override
	public void run() {
		getType(getUrl("/news-sort.html"));
	}
	
	public static void main(String[] args) throws Exception{
//		grapAllCompany();
		grapErrCompany();
    }
	public static void grapErrCompany() {
		List<GrapErr> errs = getErrs();
		GrabQyxyCompanyDataByProxy gcd = new GrabQyxyCompanyDataByProxy();
		for(GrapErr ge : errs) {
			String type = ge.getType();
			try{
				String url = ge.getUrl();
				if(url.contains("企") || ge.getDescription().contains("HTTP error fetching URL") || ge.getDescription().contains("获取Detail 内容错误：null")) {
					delErr(ge.getId());
					continue;
				}
				if(type.equals("1") || type.equals("2")) {
					gcd.getType(url);
				} else if(type.equals("3") || type.equals("4")) {
					gcd.getPage(JSON.parseObject(ge.getContent(), ComType.class));
				} else if(type.equals("5") || type.equals("6")) {
					String[] cts = ge.getContent().split(",");
					gcd.code = cts[3];
					gcd.baseUrl = "http://"+gcd.code+".qiyexinyong.org";
					gcd.getList(url, cts[0], cts[1], cts[2]);
				} else if(type.equals("7") || type.equals("8")) {
					String content = ge.getContent();
					String[] cts = content.split(",");
					gcd.code = cts[3];
					gcd.baseUrl = "http://"+gcd.code+".qiyexinyong.org";
					gcd.getDetail(url, cts[0], cts[1], cts[2]);
				} 
				updateErr(ge.getId());
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	public static void grapAllCompany() {
		List<String> urls = new  ArrayList<String>();
		urls.add("zj");
		urls.add("cq");
		urls.add("sh");
		urls.add("gz");
		urls.add("sz");
		urls.add("dg");
		
		urls.add("fs");
		urls.add("st");
		urls.add("hz");
//		urls.add("nb");
		urls.add("wz");
		urls.add("xm");
		
		urls.add("wh");
		urls.add("qd");
		urls.add("hn");
//		urls.add("zz");
		urls.add("hb");
		urls.add("qz");
		for(String url : urls) {
			GrabQyxyCompanyDataByProxy gkd = new GrabQyxyCompanyDataByProxy();
			gkd.code = url;
			gkd.baseUrl = "http://"+url+".qiyexinyong.org";
			Thread t = new Thread(gkd);
			t.start();
		}
	}
	
	private String getUrl(String url) {
		return url.startsWith("http://") ? url :  baseUrl + url;
	}
	
	/**
	 * 获取头部导航菜单
	 * @param url
	 * @throws FailingHttpStatusCodeException
	 * @throws MalformedURLException
	 * @throws IOException
	 */
	public void getType(String url) {
		Document doc = null;
		try {
			doc = GenericGrap.getDocByIp(url);
		} catch (IOException e) {
			GrapErr ge = new  GrapErr();
			ge.setUrl(url);
			ge.setType("1");
			ge.setContent("获取链接错误");
			ge.setDescription("获取Type错误："+e.getMessage());
			insert2ErrDb(ge);
			return;
		}
		
		if(null == doc) return;
		Element el = null;
		List<ComType> cts = new ArrayList<ComType>();
		try {
			el = doc.getElementsByAttributeValue("class", "h2_content").first();
			Elements aels = el.getElementsByTag("a");
			if(aels == null || aels.size() ==0) return;
			Elements spanels = el.getElementsByTag("span");
			if(spanels == null || spanels.size() ==0) return;
			for(int i=0; i< aels.size(); i++) {
				ComType ct = new ComType();
				ct.setArea(code);
				ct.setCompanyNum(spanels.get(i).text().replace("(", "").replace(")", ""));
				String comurl = aels.get(i).attr("href");
				ct.setTypeCode(comurl.substring(comurl.indexOf("-")+1, comurl.indexOf(".")));
				ct.setSourceUrl(getUrl(comurl));
				ct.setTypeName(aels.get(i).text().replace("企业名录", ""));
				cts.add(ct);
			}
		} catch (Exception e) {
			GrapErr ge = new  GrapErr();
			ge.setUrl(url);
			ge.setType("2");
			ge.setContent("获取内容错误");
			ge.setDescription("获取Type错误："+e.getMessage());
			insert2ErrDb(ge);
			return;
		}
		insert2ComTypeDb(cts);
		
		for(ComType ct : cts) {
			getPage(ct);
		}
	}
	
	/**
	 * 获取分页数据
	 * @param url
	 * @throws FailingHttpStatusCodeException
	 * @throws MalformedURLException
	 * @throws IOException
	 */
	public void getPage(ComType com) {
		System.out.println(code + "==page=" + com.getSourceUrl());
		Document doc = null;
		try {
			doc = GenericGrap.getDocByIp(com.getSourceUrl());
		} catch(Exception e) {
			GrapErr ge = new  GrapErr();
			ge.setUrl(com.getSourceUrl());
			ge.setType("3");
			ge.setContent(JSON.toJSONString(com));
			ge.setDescription("获取Page 链接错误："+e.getMessage());
			insert2ErrDb(ge);
			return;
		}
		
		Map<String, String> cityMap = new HashMap<String, String>();
		Element el = null;
		try {
			el = doc.getElementsByAttributeValue("class", "h2_content").first();
			
			Elements aels = el.getElementsByTag("a");
			if(null == aels || aels.isEmpty()) return;
			for(int i=0; i< aels.size(); i++) {
				cityMap.put(getUrl(aels.get(i).attr("href")), aels.get(i).text());
			}
			
		} catch (Exception e) {
			GrapErr ge = new  GrapErr();
			ge.setUrl(com.getSourceUrl());
			ge.setType("4");
			ge.setContent(JSON.toJSONString(com));
			ge.setDescription("获取Page 内容错误："+e.getMessage());
			insert2ErrDb(ge);
			return;
		}
		for(String url : cityMap.keySet()) {
			getList(url, cityMap.get(url), com.getTypeCode(), com.getTypeName());
		}
	}

	public void getList(String url, String city, String tc, String tn) {
		System.out.println(code + "==list=" + url);
		Document doc = null;
		try {
			doc = GenericGrap.getDocByIp(url);
		} catch(Exception e) {
			GrapErr ge = new  GrapErr();
			ge.setUrl(url);
			ge.setType("5");
			ge.setContent(city+","+tc+","+tn+","+code);
			ge.setDescription("获取List错误："+e.getMessage());
			insert2ErrDb(ge);
			return;
		}
		
		List<String> detailUrls = new ArrayList<String>();
		Element el = null;
		try {
			el = doc.getElementById("ec_table_body");
			if(null != el) {
				Elements els = el.getElementsByTag("a");
				if(null == els || els.isEmpty()) return;
				if(null != els && !els.isEmpty()) {
					for(Element ael : els) {
						detailUrls.add(getUrl(ael.attr("href")));
					}
				}
			}
		} catch(Exception e) {
			GrapErr ge = new  GrapErr();
			ge.setUrl(url);
			ge.setType("6");
			ge.setContent(city+","+tc+","+tn+","+code);
			ge.setDescription("获取List错误："+e.getMessage());
			insert2ErrDb(ge);
			return;
		}
		List<ComCompany> ccs = new ArrayList<ComCompany>();
		for(String detailUrl : detailUrls) {
			try {
				ComCompany cc = getDetail(detailUrl, city, tc, tn);
				if(null != cc) ccs.add(cc);
			} catch (Exception e) {
				GrapErr ge = new  GrapErr();
				ge.setUrl(url);
				ge.setType("7");
				ge.setContent(city+","+tc+","+tn+","+code);
				ge.setDescription("获取Detail出错："+e.getMessage());
				insert2ErrDb(ge);
				return;
			}
		}
		insert2ComDb(ccs);
	}

	public ComCompany getDetail(String url, String city, String tc, String tn) {
		Document doc = null;
		try {
			doc = GenericGrap.getDocByIp(url);
		} catch(Exception e) {
			GrapErr ge = new  GrapErr();
			ge.setUrl(url);
			ge.setType("8");
			ge.setContent(city+","+tc+","+tn+","+code);
			ge.setDescription("获取Detail 链接错误："+e.getMessage());
			insert2ErrDb(ge);
			return null;
		}
		
		Elements els = null;
		try {
			els = doc.getElementsByAttributeValue("class", "table01").first().getElementsByTag("td");
		} catch (Exception e) {
			GrapErr ge = new  GrapErr();
			ge.setUrl(url);
			ge.setType("9");
			ge.setContent(city+","+tc+","+tn+","+code);
			ge.setDescription("获取Detail 内容错误："+e.getMessage());
			insert2ErrDb(ge);
			return null;
		}
		ComCompany cc = new ComCompany();
		cc.setTypeCode(tc);
		cc.setTypeName(tn);
		cc.setSource(soruce);
		cc.setSourceUrl(url);
		cc.setProvinceCode(code);
		cc.setCityName(city);
		Element el = els.get(1);
		if(null != el) cc.setRegNum(el.text());
		el = els.get(3);
		if(null != el) {
			String typeName = el.text();
			if(typeName.length() > 25) typeName = null;
			cc.setCompanyType(typeName);
		}
		el = els.get(5);
		if(null != el) {
			cc.setCompanyName(el.text());
			cc.setName(el.text());
		}
		el = els.get(7);
		if(null != el) cc.setPrincipal(el.text());
		el = els.get(9);
		if(null != el) cc.setArea(el.text());
		el = els.get(11);
		if(null != el) cc.setCreateDate(el.text());
		el = els.get(13);
		if(null != el) cc.setRegCapital(el.text());
		el = els.get(15);
		if(null != el) cc.setStatus(el.text());
		el = els.get(17);
		if(null != el) cc.setAddress(el.text());
		el = els.get(19);
		if(null != el) cc.setBusinessScope(el.text());
		el = els.get(21);
		if(null != el) cc.setLastUpdate(el.text());
		return cc;
	}
	
	public void insert2ComDb(List<ComCompany> ccs) {
		String sql = "insert into com_company(name, city_name,reg_num,principal,create_date,status,company_type,company_name,area,reg_capital,address,business_scope,last_update,province_code, source_url,source,type_code,type_name) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
		PreparedStatement ps = null;
		try {
			ps = DbUtil.getComConn().prepareStatement(sql);
			/**
			 * name, city_name,reg_num,principal,create_date,status
			 * ,company_type,company_name,area,reg_capital,address,business_scope,last_update,province_code, source_url,source,type_code,type_name
			 */
			for(ComCompany cc : ccs) {
			ps.setString(1, cc.getName());
			ps.setString(2, cc.getCityName());
			ps.setString(3, cc.getRegNum());
			ps.setString(4, cc.getPrincipal());
			ps.setString(5, cc.getCreateDate());

			ps.setString(6, cc.getStatus());
			ps.setString(7, cc.getCompanyType());
			ps.setString(8, cc.getCompanyName());
			ps.setString(9, cc.getArea());
			ps.setString(10, cc.getRegCapital());

			ps.setString(11, cc.getAddress());
			ps.setString(12, cc.getBusinessScope());
			ps.setString(13, cc.getLastUpdate());
			ps.setString(14, cc.getProvinceCode());
			ps.setString(15, cc.getSourceUrl());
			ps.setString(16, cc.getSource());
			ps.setString(17, cc.getTypeCode());
			ps.setString(18, cc.getTypeName());
			ps.addBatch();
			}
			ps.executeBatch();	
		} catch (Exception e) {
			GrapErr ge = new  GrapErr();
			ge.setType("10");
			ge.setContent(JSON.toJSONString(ccs));
			ge.setDescription("获取Detail错误："+e.getMessage());
			insert2ErrDb(ge);
			return;
		} finally {
			if(null != ps) {
				try {
					ps.close();
				} catch (SQLException e) {
					
				}
			}
		}
	}
	
	public static void insert2ComTypeDb(List<ComType> cts) {
		String sql = "insert into com_type(type_code,type_name,company_num,source_url,area) values(?,?,?,?,?)";
		PreparedStatement ps = null;
		try {
			ps = DbUtil.getComConn().prepareStatement(sql);
			for(ComType ct : cts) {
				// type_code,type_name,company_num,source_url,area
				ps.setString(1, ct.getTypeCode());
				ps.setString(2, ct.getTypeName());
				ps.setString(3, ct.getCompanyNum());
				ps.setString(4, ct.getSourceUrl());
				ps.setString(5, ct.getArea());
				ps.addBatch();
			}
			ps.executeBatch();	
		} catch (Exception e) {
			
		} finally {
			if(null != ps) {
				try {
					ps.close();
				} catch (SQLException e) {
					
				}
			}
		}
	}

	public void insert2ErrDb(GrapErr ge) {
		PreparedStatement grapPs = null;
		try {
			grapPs = DbUtil.getComConn().prepareStatement("insert into grap_err(description,url,content,type) values(?,?,?,?)");
			grapPs.setString(1, ge.getDescription());
			grapPs.setString(2, ge.getUrl());
			grapPs.setString(3, ge.getContent());
			grapPs.setString(4, ge.getType());
			grapPs.execute();
			grapPs.close();
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			if(null != grapPs) {
				try {
					grapPs.close();
				} catch (SQLException e) {
					
				}
			}
		}
	}
	
	public static List<GrapErr> getErrs() {
		List<GrapErr> univs = new ArrayList<GrapErr>();
		try {
			Connection connection = DbUtil.getComConn();
			Statement statement = connection.createStatement();
			String sql = "select * from grap_err";
			ResultSet rs = statement.executeQuery(sql);
			while(rs.next()) {
				GrapErr univ = new GrapErr();
				univ.setId(rs.getInt("id"));
				univ.setUrl(rs.getString("url"));
				univ.setType(rs.getString("type"));
				univ.setContent(rs.getString("content"));
				univ.setDescription(rs.getString("description"));
				univs.add(univ);
			}
			rs.close();
			statement.close();
		} catch(Exception e) {
			e.printStackTrace();
		}
		return univs;
	}
	
	public static void delErr(int id) {
		PreparedStatement grapPs = null;
		try {
			grapPs = DbUtil.getComConn().prepareStatement("delete from grap_err where id=?");
			grapPs.setInt(1, id);
			grapPs.execute();
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			if(null != grapPs) {
				try {
					grapPs.close();
				} catch (SQLException e) {
					
				}
			}
		}
	}
	
	public static void updateErr(int id) {
		PreparedStatement grapPs = null;
		try {
			grapPs = DbUtil.getComConn().prepareStatement("update grap_err set state =1 where id=?");
			grapPs.setInt(1, id);
			grapPs.execute();
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			if(null != grapPs) {
				try {
					grapPs.close();
				} catch (SQLException e) {
					
				}
			}
		}
	}
}
